package com.xqq.lottery.net;

import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.ReentrantLock;
import java.util.zip.DataFormatException;

import org.apache.commons.lang3.StringUtils;

import com.xqq.lottery.ConstantValue;
import com.xqq.lottery.bean.MessageItem;
import com.xqq.lottery.protocal.MessageType;
import com.xqq.lottery.protocal.protobuf.Heart;
import com.xqq.lottery.util.MessageUtil;

import android.app.AlarmManager;
import android.app.IntentService;
import android.app.Service;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;

public class NoticeService extends Service {
	
	private static final String TAG ="NoticeService";
	public static boolean isOpen = false;
    private AlarmManager alarmManager;
    private SocketAdapter socket;
    private MyHandler handler;
    private boolean isReconnected = false;
    private CountDownLatch latch = null;
    
    private Thread receiveThread; //接收线程
    private Thread sendThread;  //发送线程
    private Thread sendActiveThread; //心跳线程
    private final ReentrantLock lock = new ReentrantLock();
    
    
    @Override
    public void onCreate() {
    	handler =new MyHandler();
    	super.onCreate();
    }
    
	@Override
	public IBinder onBind(Intent arg0) {
		return null;
	}
	
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		isOpen = true;
		Log.e(TAG, "开启服务");
		int flag = intent.getIntExtra(ConstantValue.NOTICE_FLAG, 0);
		//获取当前socket连接，判断是否是连接状态
		boolean isConnected = checkSocket();
		if(isConnected){
			switch(flag){
			case ConstantValue.NOTICE_CHANGE_NET:   //网络发生变化
				socket.setSendSwitch(false);
				socket.close();
				Log.i(TAG, "network change.");
				reConnected(false);
				//重新连接
				break;
			case ConstantValue.NOTICE_CHANGE_SETTING:  //设置发生变化
				SharedPreferences sp =getSharedPreferences(ConstantValue.SETTING_NAME, MODE_PRIVATE);
				//boolean lotterySet = sp.getBoolean(arg0, arg1)
				break;
			case ConstantValue.NOTICE_CHANGE_CLOSE:
				socket.setSendSwitch(false);
				socket.close();
				break;
			default:
				break;
			}
		}
		isConnected = checkSocket();
		if(!isConnected){
		    if(openConnection()){
		    	writeInfo();
		    	openReceive();
		    	sendActive();
		    }
		}
		return super.onStartCommand(intent, flags, startId);
	}
	
	
	
	/**
	 * 开启接收线程
	 */
	private void openReceive(){
		Runnable receiveRunnable =new Runnable() {
			@Override
			public void run() {
				InputStream inputStream = null;
				try{
					Log.i(TAG, "start receive info.");
					socket = SocketAdapter.getSocketAdapterInstance();
					inputStream = socket.openInputStream();
					while(socket.isSendSwitch()){
						//读取数据进行解析
						final MessageItem  msgItem =NetUtil.readData(inputStream);  //读取数据
						//将数据放入线程池中进行解析
						MessageUtil.receivePoolExecutorService.execute(new Runnable() {
							
							@Override
							public void run() {
								handleReceiveInfo(msgItem);
							}
						});
					}
					
				}catch(Exception e){
					Log.e(TAG, "接收消息出错，开始重新连接");
					startReconnected();
				}finally{
					if(inputStream != null){
						try {
							inputStream.close();
						} catch (IOException e) {
							e.printStackTrace();
						}
					}
				}
			}
		};
		receiveThread = new Thread(receiveRunnable);
		receiveThread.start();
	}
	
	private void handleReceiveInfo(MessageItem msgItem){
		//处理接收的数据
		MessageUtil.handlMessage(msgItem);
	}
	
	/**
	 * 发送消息
	 */
	private void writeInfo(){
		sendThread =  new Thread(new Runnable() {
			@Override
			public void run() {
				Log.i(TAG, "start send info");
				try {
					while(socket.isSendSwitch()){
						MessageItem msgItem = MessageUtil.getMsgItem();
						NetUtil.sendData(socket.openOutputStream(), msgItem);
					}
				} catch (Exception e) {
					Log.e(TAG, "发送消息失败开始重新连接!准备开始重新连接");
					startReconnected();
				}
			}
		});
		sendThread.start();
	}
	
	private  void setWaitStatus(){
	}
	
	
	/**
	 * 发送心跳数据
	 */
	private void sendActive(){
		MessageUtil.activeSingleThreadPool.execute(new Runnable() {
			@Override
			public void run() {
				while(socket.isSendSwitch()){
					if(MessageUtil.isOutTimed()){
						//构造心跳包数据
						Heart.MessageHeart.Builder builder = Heart.MessageHeart.newBuilder();
						builder.setId(110);
						MessageItem msgItem =new MessageItem();
						msgItem.setMsgType(MessageType.MSG_HEART);
						msgItem.setMsgContent(builder.build().toByteArray());
					    MessageUtil.insertSendQueue(msgItem);
					    try {
							Thread.sleep(6*1000);   //每6秒发送一次心跳数据
						} catch (InterruptedException e) {
							break;
						}
					}else{
						Log.e(TAG, "心跳检测断开连接");
						startReconnected();
						socket.setSendSwitch(false);
						break;
					}
				}
			}
		});
	}
	
	/**
	 * 重新连接
	 */
	private synchronized void  closeSocket(){
		if(socket != null){
			socket.setSendSwitch(false);
			socket.close();
		}
	}
	
	private void startReconnected(){
		reConnected(true);
	}
	
	private void reConnected(boolean isDelay){
		Log.i(TAG, "reconnected.....");
		if(socket != null){
			socket.setSendSwitch(false);
			socket.close();
		}
		if(isDelay){
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		openConnection();
	}
	
	/**
	 * 建立连接
	 * @return
	 */
	private boolean openConnection(){
		try {
			Log.e(TAG, "开始连接");
			String getNowAPN = NetUtil.GetNowAPN(NoticeService.this);
			if ("cmwap".equals(getNowAPN)) {
				System.getProperties().put("socksProxySet ", "true ");
				System.getProperties().put("socksProxyHost ", GloablParams.PROXY);
				System.getProperties().put("socksProxyPort ", GloablParams.PORT);
			}
			socket = SocketAdapter.getSocketAdapterInstance("192.168.100.2", 8811);
			Log.e(TAG, "连接打开成功");
			return true;
		} catch (IOException e) {
			e.printStackTrace();
			Log.e(TAG, "open socket error(ip:" + GloablParams.PROXY + ";port:" + GloablParams.PORT + ")");
			return false;
		}					
				
	}
	
	class MyHandler extends Handler{
		@Override
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case 1:
				Log.e(TAG, "成功连接到服务器");
				MessageUtil.updateHearTime();
				writeInfo();
				sendActive();
				openReceive();
				break;
			default:
				break;
			}
			super.handleMessage(msg);
		}
	}
	
	
	
	/**
	 * 获取当前socket连接，判断是否是连接状态
	 * @return
	 */
	private boolean checkSocket(){
		socket = SocketAdapter.getSocketAdapterInstance();
		if(socket != null){
			return socket.isSendSwitch();
		}
		return false;
	}
	
	@Override
	public void onDestroy() {
		isOpen = false;
		if(socket != null){
			socket.setSendSwitch(false);
			socket.close();
		}
		super.onDestroy();
	}

}
